﻿using System;

namespace AsmShaderConverter.AsmShader
{
    public class AsmShaderHelper
    {
        internal static AsmSemantics ConvertTo(string semantic)
        {
            switch (semantic)
            {
                case "dcl_position": return AsmSemantics.dcl_position;
                case "dcl": return AsmSemantics.dcl; // VPos
                case "dcl_normal": return AsmSemantics.dcl_normal;
                case "dcl_texcoord": return AsmSemantics.dcl_texcoord;
                case "dcl_texcoord0": return AsmSemantics.dcl_texcoord0;
                case "dcl_texcoord1": return AsmSemantics.dcl_texcoord1;
                case "dcl_texcoord2": return AsmSemantics.dcl_texcoord2;
                case "dcl_texcoord3": return AsmSemantics.dcl_texcoord3;
                case "dcl_texcoord4": return AsmSemantics.dcl_texcoord4;
                case "dcl_texcoord5": return AsmSemantics.dcl_texcoord5;
                case "dcl_texcoord6": return AsmSemantics.dcl_texcoord6;
                case "dcl_texcoord7": return AsmSemantics.dcl_texcoord7;
                case "dcl_texcoord8": return AsmSemantics.dcl_texcoord8;
                case "dcl_color": return AsmSemantics.dcl_color;
                case "dcl_color1": return AsmSemantics.dcl_color1;
                case "dcl_color2": return AsmSemantics.dcl_color2;
                case "dcl_color3": return AsmSemantics.dcl_color3;
                case "dcl_color4": return AsmSemantics.dcl_color4;
                case "dcl_color5": return AsmSemantics.dcl_color5;
                case "dcl_color6": return AsmSemantics.dcl_color6;
                case "dcl_color7": return AsmSemantics.dcl_color7;
                case "dcl_color8": return AsmSemantics.dcl_color8;
                case "dcl_fog": return AsmSemantics.dcl_fog;

                default:
                    throw new Exception("unknown semantic");
            }
        }

        internal static HlslShader.HlslSemantics ConvertAsmSemantivToHlsl(AsmSemantics asmSemantic, ShaderType shaderVersion, ShaderVersion version, AsmShaderInputOutput.DataDirection dataDirection)
        {
            switch (shaderVersion)
            {
                case ShaderType.PixelShader:
                    return ConvertAsmSemantivToHlsl_PS(asmSemantic, version, dataDirection);

                case ShaderType.VertexShader:
                    return ConvertAsmSemantivToHlsl_VS(asmSemantic, dataDirection);

                default:
                    throw new Exception("unknown ShaderVersion: " + shaderVersion.ToString());
            }
        }

        internal static HlslShader.HlslSemantics ConvertAsmSemantivToHlsl_PS(AsmSemantics asmSemantic, ShaderVersion version, AsmShaderInputOutput.DataDirection dataDirection)
        {
            switch (version)
            {
                case ShaderVersion.V2_0:
                    switch (asmSemantic)
                    {
                        case AsmSemantics.dcl: return HlslShader.HlslSemantics.Vpos;
                        case AsmSemantics.dcl_color: return HlslShader.HlslSemantics.color;
                        case AsmSemantics.dcl_color1: return HlslShader.HlslSemantics.color1;
                        case AsmSemantics.dcl_color2: return HlslShader.HlslSemantics.color2;
                        case AsmSemantics.dcl_color3: return HlslShader.HlslSemantics.color3;
                        case AsmSemantics.dcl_color4: return HlslShader.HlslSemantics.color4;
                        case AsmSemantics.dcl_color5: return HlslShader.HlslSemantics.color5;
                        case AsmSemantics.dcl_color6: return HlslShader.HlslSemantics.color6;
                        case AsmSemantics.dcl_color7: return HlslShader.HlslSemantics.color7;
                        case AsmSemantics.dcl_color8: return HlslShader.HlslSemantics.color8;
                        case AsmSemantics.dcl_normal: return HlslShader.HlslSemantics.normal;
                        // case AsmSemantics.dcl_position: return HlslShader.HlslSemantics.SV_Posiont; // überprüfen
                        case AsmSemantics.dcl_texcoord: return HlslShader.HlslSemantics.texcoord;
                        case AsmSemantics.dcl_texcoord0: return HlslShader.HlslSemantics.texcoord0;
                        case AsmSemantics.dcl_texcoord1: return HlslShader.HlslSemantics.texcoord1;
                        case AsmSemantics.dcl_texcoord2: return HlslShader.HlslSemantics.texcoord2;
                        case AsmSemantics.dcl_texcoord3: return HlslShader.HlslSemantics.texcoord3;
                        case AsmSemantics.dcl_texcoord4: return HlslShader.HlslSemantics.texcoord4;
                        case AsmSemantics.dcl_texcoord5: return HlslShader.HlslSemantics.texcoord5;
                        case AsmSemantics.dcl_texcoord6: return HlslShader.HlslSemantics.texcoord6;
                        case AsmSemantics.dcl_texcoord7: return HlslShader.HlslSemantics.texcoord7;
                        case AsmSemantics.dcl_texcoord8: return HlslShader.HlslSemantics.texcoord8;
                        case AsmSemantics.dcl_position: return HlslShader.HlslSemantics.SV_Position;

                        default:
                            throw new Exception("Can´t convert asm semantiv to hlsl semantic");
                    }
                case ShaderVersion.V5_0:
                    switch (asmSemantic)
                    {
                        case AsmSemantics.dcl: return HlslShader.HlslSemantics.SV_Position;
                        case AsmSemantics.dcl_color: return HlslShader.HlslSemantics.color;
                        case AsmSemantics.dcl_color1: return HlslShader.HlslSemantics.color1;
                        case AsmSemantics.dcl_color2: return HlslShader.HlslSemantics.color2;
                        case AsmSemantics.dcl_color3: return HlslShader.HlslSemantics.color3;
                        case AsmSemantics.dcl_color4: return HlslShader.HlslSemantics.color4;
                        case AsmSemantics.dcl_color5: return HlslShader.HlslSemantics.color5;
                        case AsmSemantics.dcl_color6: return HlslShader.HlslSemantics.color6;
                        case AsmSemantics.dcl_color7: return HlslShader.HlslSemantics.color7;
                        case AsmSemantics.dcl_color8: return HlslShader.HlslSemantics.color8;
                        case AsmSemantics.dcl_normal: return HlslShader.HlslSemantics.normal;
                        // case AsmSemantics.dcl_position: return HlslShader.HlslSemantics.SV_Posiont; // überprüfen
                        case AsmSemantics.dcl_texcoord: return HlslShader.HlslSemantics.texcoord;
                        case AsmSemantics.dcl_texcoord0: return HlslShader.HlslSemantics.texcoord0;
                        case AsmSemantics.dcl_texcoord1: return HlslShader.HlslSemantics.texcoord1;
                        case AsmSemantics.dcl_texcoord2: return HlslShader.HlslSemantics.texcoord2;
                        case AsmSemantics.dcl_texcoord3: return HlslShader.HlslSemantics.texcoord3;
                        case AsmSemantics.dcl_texcoord4: return HlslShader.HlslSemantics.texcoord4;
                        case AsmSemantics.dcl_texcoord5: return HlslShader.HlslSemantics.texcoord5;
                        case AsmSemantics.dcl_texcoord6: return HlslShader.HlslSemantics.texcoord6;
                        case AsmSemantics.dcl_texcoord7: return HlslShader.HlslSemantics.texcoord7;
                        case AsmSemantics.dcl_texcoord8: return HlslShader.HlslSemantics.texcoord8;
                        case AsmSemantics.dcl_position: return HlslShader.HlslSemantics.SV_Position;
                        case AsmSemantics.dcl_fog: return HlslShader.HlslSemantics.FOG;

                        default:
                            throw new Exception("Can´t convert asm semantiv to hlsl semantic");
                    }
            }
            throw new Exception("Can´t convert asm semantiv to hlsl semantic");
        }

        internal static HlslShader.HlslSemantics ConvertAsmSemantivToHlsl_VS(AsmSemantics asmSemantic, AsmShaderInputOutput.DataDirection dataDirection)
        {
            switch (dataDirection)
            {
                case AsmShaderInputOutput.DataDirection.In:
                    switch (asmSemantic)
                    {
                        case AsmSemantics.dcl: return HlslShader.HlslSemantics.Vpos;
                        case AsmSemantics.dcl_color: return HlslShader.HlslSemantics.color;
                        case AsmSemantics.dcl_color1: return HlslShader.HlslSemantics.color1;
                        case AsmSemantics.dcl_color2: return HlslShader.HlslSemantics.color2;
                        case AsmSemantics.dcl_color3: return HlslShader.HlslSemantics.color3;
                        case AsmSemantics.dcl_color4: return HlslShader.HlslSemantics.color4;
                        case AsmSemantics.dcl_color5: return HlslShader.HlslSemantics.color5;
                        case AsmSemantics.dcl_color6: return HlslShader.HlslSemantics.color6;
                        case AsmSemantics.dcl_color7: return HlslShader.HlslSemantics.color7;
                        case AsmSemantics.dcl_color8: return HlslShader.HlslSemantics.color8;
                        case AsmSemantics.dcl_normal: return HlslShader.HlslSemantics.normal;
                        // case AsmSemantics.dcl_position: return HlslShader.HlslSemantics.SV_Posiont; // überprüfen
                        case AsmSemantics.dcl_texcoord: return HlslShader.HlslSemantics.texcoord;
                        case AsmSemantics.dcl_texcoord0: return HlslShader.HlslSemantics.texcoord0;
                        case AsmSemantics.dcl_texcoord1: return HlslShader.HlslSemantics.texcoord1;
                        case AsmSemantics.dcl_texcoord2: return HlslShader.HlslSemantics.texcoord2;
                        case AsmSemantics.dcl_texcoord3: return HlslShader.HlslSemantics.texcoord3;
                        case AsmSemantics.dcl_texcoord4: return HlslShader.HlslSemantics.texcoord4;
                        case AsmSemantics.dcl_texcoord5: return HlslShader.HlslSemantics.texcoord5;
                        case AsmSemantics.dcl_texcoord6: return HlslShader.HlslSemantics.texcoord6;
                        case AsmSemantics.dcl_texcoord7: return HlslShader.HlslSemantics.texcoord7;
                        case AsmSemantics.dcl_texcoord8: return HlslShader.HlslSemantics.texcoord8;
                        case AsmSemantics.dcl_position: return HlslShader.HlslSemantics.Position;

                        default:
                            throw new Exception("Can´t convert asm semantiv to hlsl semantic");
                    }
                case AsmShaderInputOutput.DataDirection.Out:
                    switch (asmSemantic)
                    {
                        case AsmSemantics.dcl: return HlslShader.HlslSemantics.Vpos;
                        case AsmSemantics.dcl_color: return HlslShader.HlslSemantics.color;
                        case AsmSemantics.dcl_color1: return HlslShader.HlslSemantics.color1;
                        case AsmSemantics.dcl_color2: return HlslShader.HlslSemantics.color2;
                        case AsmSemantics.dcl_color3: return HlslShader.HlslSemantics.color3;
                        case AsmSemantics.dcl_color4: return HlslShader.HlslSemantics.color4;
                        case AsmSemantics.dcl_color5: return HlslShader.HlslSemantics.color5;
                        case AsmSemantics.dcl_color6: return HlslShader.HlslSemantics.color6;
                        case AsmSemantics.dcl_color7: return HlslShader.HlslSemantics.color7;
                        case AsmSemantics.dcl_color8: return HlslShader.HlslSemantics.color8;
                        case AsmSemantics.dcl_normal: return HlslShader.HlslSemantics.normal;
                        // case AsmSemantics.dcl_position: return HlslShader.HlslSemantics.SV_Posiont; // überprüfen
                        case AsmSemantics.dcl_texcoord: return HlslShader.HlslSemantics.texcoord;
                        case AsmSemantics.dcl_texcoord0: return HlslShader.HlslSemantics.texcoord0;
                        case AsmSemantics.dcl_texcoord1: return HlslShader.HlslSemantics.texcoord1;
                        case AsmSemantics.dcl_texcoord2: return HlslShader.HlslSemantics.texcoord2;
                        case AsmSemantics.dcl_texcoord3: return HlslShader.HlslSemantics.texcoord3;
                        case AsmSemantics.dcl_texcoord4: return HlslShader.HlslSemantics.texcoord4;
                        case AsmSemantics.dcl_texcoord5: return HlslShader.HlslSemantics.texcoord5;
                        case AsmSemantics.dcl_texcoord6: return HlslShader.HlslSemantics.texcoord6;
                        case AsmSemantics.dcl_texcoord7: return HlslShader.HlslSemantics.texcoord7;
                        case AsmSemantics.dcl_texcoord8: return HlslShader.HlslSemantics.texcoord8;
                        case AsmSemantics.dcl_position: return HlslShader.HlslSemantics.SV_Position;
                        case AsmSemantics.dcl_fog: return HlslShader.HlslSemantics.FOG;

                        default:
                            throw new Exception("Can´t convert asm semantiv to hlsl semantic");
                    }

                default:
                    throw new Exception("Can´t convert asm semantiv to hlsl semantic");
            }
        }

        public enum ShaderType
        {
            None,
            VertexShader,
            PixelShader
        }

        public enum ShaderVersion
        {
            V1_0,
            V1_1,
            V1_2,
            V1_3,
            V1_4,
            V2_0,
            V2_a,
            V2_b,
            V3_0,
            V4_0,
            V4_1,
            V5_0,
        }
    }
}